﻿using System.Collections.Generic;
using System.Linq;
#if ODIN_INSPECTOR
using Sirenix.OdinInspector;
#endif
using UnityEngine;
using UnityEngine.Profiling;

namespace JH
{
    /// <summary>
    ///  固定容量的去重图表数据基类
    /// </summary>
    public abstract class FixedBasicChart<TPoint> : BasicChart<TPoint>
        where TPoint : struct
    {
        /// <summary>
        ///  最大容量
        /// </summary>
        [SerializeField]
#if ODIN_INSPECTOR
        [LabelText("最大容量")]
#endif
        private int maxSize;

        /// <summary>
        ///  获取原始数据的最大容量
        /// </summary>
        public int MaxSize => maxSize;

#if UNITY_EDITOR
        /// <summary>
        ///  编辑器下的真实数据的集合
        /// </summary>
        [SerializeField]
#if ODIN_INSPECTOR
        [LabelText("真实数据")]
        [ReadOnly]
#endif
        private List<TPoint> realData;
#endif

        /// <summary>
        ///  序列化的固定容量数组
        /// </summary>
        private FixedUniqueArray<TPoint> _dataList;

        /// <summary>
        ///  去重比较器
        /// </summary>
        protected abstract IEqualityComparer<TPoint> Comparer { get; }

        /// <summary>
        ///  基类使用的数据点集合
        /// </summary>
        protected override ICollection<TPoint> DataList
        {
            get
            {
                // 如果数据列表为空或者容量变化， 则重新创建一个新的FixedUniqueArray
                if (_dataList == null || _dataList.MaxSize != maxSize)
                    _dataList = new FixedUniqueArray<TPoint>(maxSize, Comparer);

                return _dataList;
            }
        }

        protected override void OnValidate()
        {
            _dataList = null;
            maxSize = Mathf.Max(1, maxSize);
            var overflow = editorPoint.Count - maxSize;
            for (int i = 0; i < overflow; i++) editorPoint.RemoveAt(0);
            base.OnValidate();
#if UNITY_EDITOR
            realData = DataList.ToList();
#endif
        }

        protected virtual void LateUpdate()
        {
#if UNITY_EDITOR
            Profiler.BeginSample("Editor Only");
            realData = DataList.ToList();
            Profiler.EndSample();
#endif
        }
    }
}